#include "task_manager.h"

/* 按键扫描任务 */
void ScanKeyTask(void)
{
    cotKey_Scan(HAL_GetTick());
}

/* LED扫描任务 */
void ScanLedTask(void)
{
    cotLed_Ctrl(HAL_GetTick());
}

/* 调度测试任务 */
void TestScheduleTask(void)
{
    static uint32_t counter = 0;
    static uint32_t lastTime = 0;
    uint32_t currentTime = HAL_GetTick();
    counter++;
    printf("Task executed: %ld, interval: %ldms\r\n", counter, currentTime - lastTime);
    lastTime = currentTime;
}

/* ADC测试任务 */
void InitADCTest(void)
{
    adc_nch_dma_init((uint32_t)&g_adc_dma_buf); /* 初始化多通道ADC DMA采集 */
    lcd_show_string(30, 110, 200, 12, 12, "ADC1_CH0_VAL:", BLUE);
    lcd_show_string(30, 122, 200, 12, 12, "ADC1_CH0_VOL:0.000V", BLUE); /* 先在固定位置显示小数点 */

    lcd_show_string(30, 140, 200, 12, 12, "ADC1_CH1_VAL:", BLUE);
    lcd_show_string(30, 152, 200, 12, 12, "ADC1_CH1_VOL:0.000V", BLUE); /* 先在固定位置显示小数点 */

    lcd_show_string(30, 170, 200, 12, 12, "ADC1_CH2_VAL:", BLUE);
    lcd_show_string(30, 182, 200, 12, 12, "ADC1_CH2_VOL:0.000V", BLUE); /* 先在固定位置显示小数点 */

    lcd_show_string(30, 200, 200, 12, 12, "ADC1_CH3_VAL:", BLUE);
    lcd_show_string(30, 212, 200, 12, 12, "ADC1_CH3_VOL:0.000V", BLUE); /* 先在固定位置显示小数点 */

    lcd_show_string(30, 230, 200, 12, 12, "ADC1_CH4_VAL:", BLUE);
    lcd_show_string(30, 242, 200, 12, 12, "ADC1_CH4_VOL:0.000V", BLUE); /* 先在固定位置显示小数点 */

    lcd_show_string(30, 260, 200, 12, 12, "ADC1_CH5_VAL:", BLUE);
    lcd_show_string(30, 272, 200, 12, 12, "ADC1_CH5_VOL:0.000V", BLUE); /* 先在固定位置显示小数点 */
    adc_nch_dma_enable(ADC_DMA_BUF_SIZE);       /* 启动ADC DMA多通道采集 */
}

void ScanADCTask(void)
{
    uint16_t i, j;
    uint16_t adcx;
    uint32_t sum;
    float temp;
    if (g_adc_dma_sta == 1)
    {
        /* 循环显示通道0~通道5的结果 */
        for(j = 0; j < 6; j++)  /* 遍历6个通道 */
        {
            sum = 0; /* 清零 */
            for (i = 0; i < ADC_DMA_BUF_SIZE / 6; i++)  /* 每个通道采集了10次数据,进行10次累加 */
            {
                sum += g_adc_dma_buf[(6 * i) + j];  /* 相同通道的转换数据累加 */
            }
            adcx = sum / (ADC_DMA_BUF_SIZE / 6);    /* 取平均值 */
            
            /* 显示结果 */
            lcd_show_xnum(108, 110 + (j * 30), adcx, 4, 12, 0, BLUE);   /* 显示ADC采样后的原始值 */

            temp = (float)adcx * (3.3 / 4096);      /* 获取计算后的带小数的实际电压值，比如3.1111 */
            adcx = temp;    /* 赋值整数部分给adcx变量，因为adcx为u16整形 */
            lcd_show_xnum(108, 122 + (j * 30), adcx, 1, 12, 0, BLUE);   /* 显示电压值的整数部分，3.1111的话，这里就是显示3 */

            temp -= adcx;   /* 把已经显示的整数部分去掉，留下小数部分，比如3.1111-3=0.1111 */
            temp *= 1000;   /* 小数部分乘以1000，例如：0.1111就转换为111.1，相当于保留三位小数。 */
            lcd_show_xnum(120, 122 + (j * 30), temp, 3, 12, 0X80, BLUE);/* 显示小数部分（前面转换为了整形显示），这里显示的就是111. */
        }

        g_adc_dma_sta = 0;  /* 清除DMA采集完成状态标志 */
        adc_nch_dma_enable(ADC_DMA_BUF_SIZE);   /* 启动下一次ADC DMA多通道采集 */
    }
}

/* DAC测试任务 */
void InitDACTest(void)
{
    adc_init();     /* 初始化ADC1通道 5 */
    dac_init(1);    /* 初始化DAC1_OUT1通道 1:DAC_OUT_1-PA4  2:DAC_OUT_2-PA5 */
    lcd_show_string(30, 320, 200, 16, 16, "DAC VAL:", BLUE);
    lcd_show_string(30, 340, 200, 16, 16, "DAC VOL:0.000V", BLUE);
    lcd_show_string(30, 360, 200, 16, 16, "ADC VOL:0.000V", BLUE);
}

void ScanDACTask(void)
{
    uint16_t adcx;
    float temp;
    
    adcx = HAL_DAC_GetValue(&g_dac1_handle, DAC_CHANNEL_1); /* 读取前面设置DAC1_OUT1的值 */
    lcd_show_xnum(94, 320, adcx, 4, 16, 0, BLUE);           /* 显示DAC寄存器值 */

    temp = (float)adcx * (3.3 / 4096);                      /* 得到DAC电压值 */
    adcx = temp;
    lcd_show_xnum(94, 340, temp, 1, 16, 0, BLUE);           /* 显示电压值整数部分 */

    temp -= adcx;
    temp *= 1000;
    lcd_show_xnum(110, 340, temp, 3, 16, 0X80, BLUE);       /* 显示电压值的小数部分 */

    adcx = adc_get_result_average(ADC_ADCX_CHY, 20);        /* 得到ADC1通道5的转换结果 */
    temp = (float)adcx * (3.3 / 4096);                      /* 得到ADC电压值(adc是12bit的) */
    adcx = temp;
    lcd_show_xnum(94, 360, temp, 1, 16, 0, BLUE);           /* 显示电压值整数部分 */

    temp -= adcx;
    temp *= 1000;
    lcd_show_xnum(110, 360, temp, 3, 16, 0X80, BLUE);       /* 显示电压值的小数部分 */
}

/* PWM DAC测试任务 */
void InitPWMDAC_Test(void)
{
    pwmdac_init(256 - 1, 0);                /* PWM DAC初始化, Fpwm = 84 / 256 =328.125Khz */
    lcd_show_string(30, 400, 200, 16, 16, "PWM VAL:", BLUE);
    lcd_show_string(30, 420, 200, 16, 16, "DAC VOL:0.000V", BLUE);
    lcd_show_string(30, 440, 200, 16, 16, "ADC VOL:0.000V", BLUE);
    __HAL_TIM_SET_COMPARE(&g_tim9_handler, PWMDAC_TIMX_CHY, 0); /* 输出新的PWM占空比 */
}

void ScanPWMDACTask(void)
{
    uint16_t adcx;
    float temp;
    
    adcx = __HAL_TIM_GET_COMPARE(&g_tim9_handler,PWMDAC_TIMX_CHY);  /* PWM DAC 定时器输出比较值 */
    lcd_show_xnum(94, 400, adcx, 3, 16, 0, BLUE);                   /* 显示CCRX寄存器值 */

    temp = (float)adcx * (3.3 / 256);                               /* 得到DAC电压值 */
    adcx = temp;
    lcd_show_xnum(94, 420, temp, 1, 16, 0, BLUE);                   /* 显示电压值整数部分 */

    temp -= adcx;
    temp *= 1000;
    lcd_show_xnum(110, 420, temp, 3, 16, 0X80, BLUE);               /* 显示电压值的小数部分 */

    adcx = adc_get_result_average(ADC_ADCX_CHY, 10);                /* 得到ADC1通道5的转换结果 */
    temp = (float)adcx * (3.3 / 4096);                              /* 得到ADC电压值(adc是12bit的) */
    adcx = temp;
    lcd_show_xnum(94, 440, temp, 1, 16, 0, BLUE);                   /* 显示电压值整数部分 */

    temp -= adcx;
    temp *= 1000;
    lcd_show_xnum(110, 440, temp, 3, 16, 0X80, BLUE);               /* 显示电压值的小数部分 */
}

/* 光敏传感器测试任务 */
void ScanlsensTask(void)
{
    uint16_t adcx;
    adcx = lsens_get_val();                                 /* 获取ADC值 */
    lcd_show_string(30, 300, 200, 16, 16, "LSENS_VAL:", BLUE);
    lcd_show_xnum(30 + 10 * 8, 300, adcx, 3, 16, 0, BLUE);  /* 显示ADC的值 */
}

/* 24CXX测试任务 */
void AT24CXXTest(void)
{
    at24cxx_safe_test();
}

/* NORFLASH测试任务 */
void NorflashTest(void)
{
    norflash_test();
}

/* RS485测试任务 */
void InitRS485Test(void)
{
   lcd_show_string(30, 130, 200, 16, 16, "Count:", RED);       /* 显示当前计数值 */
   lcd_show_string(30, 150, 200, 16, 16, "Send Data:", RED);   /* 提示发送的数据 */
   lcd_show_string(30, 190, 200, 16, 16, "Receive Data:", RED);/* 提示接收到的数据 */
}

void RS485SendTask(void)
{
    static uint8_t i = 0;
    static uint8_t cnt = 0;
    uint8_t rs485buf[5];
    
    for (i = 0; i < 5; i++)
    {
        rs485buf[i] = cnt + i;      /* 填充发送缓冲区 */
        lcd_show_xnum(30 + i * 32, 170, rs485buf[i], 3, 16, 0X80, BLUE);    /* 显示数据 */
    }

    rs485_send_data(rs485buf, 5);   /* 发送5个字节 */
    cnt++;
    lcd_show_xnum(30 + 48, 130, cnt, 3, 16, 0X80, BLUE);                    /* 显示数据 */
}

void RS485ReceiveTask(void)
{
    static uint8_t i = 0;
    uint8_t rs485buf[5];
    uint8_t len = 0;  
    
    rs485_receive_data(rs485buf, &len); /* 使用局部变量len来接收数据长度 */

    if (len)                            /* 接收到有数据 */
    {
        if (len > 5) len = 5;           /* 最大是5个数据 */
        for (i = 0; i < len; i++)
        {
            lcd_show_xnum(30 + i * 32, 210, rs485buf[i], 3, 16, 0X80, BLUE);    /* 显示数据 */
        }
    }
}

/* SD卡检测任务 */
void InitSDCardCheck(void)
{
    while (sd_init())   /* 检测不到SD卡 */
    {
        lcd_show_string(30, 130, 200, 16, 16, "SD Card Error!", RED);
        delay_ms(500);
        lcd_show_string(30, 130, 200, 16, 16, "Please Check! ", RED);
        delay_ms(500);
        cotLed_Toggle(LED_0);    /* 红灯闪烁 */
    }

    show_sdcard_info(); /* 打印SD卡相关信息 */

    /* 检测SD卡成功 */
    lcd_show_string(30, 130, 200, 16, 16, "SD Card OK    ", BLUE);
    lcd_show_string(30, 150, 200, 16, 16, "SD Card Size:     MB", BLUE);
    lcd_show_num(30 + 13 * 8, 150, SD_TOTAL_SIZE_MB(&g_sdcard_handler), 5, 16, BLUE); /* 显示SD卡容量 */
    
    sd_test_read(0,1);  /* 从0扇区读取1*512字节的内容 */
}

/* FATFS/存储管理任务 */
void InitFATFSManager(void)
{
    uint32_t total, free;
    uint8_t res = 0;
    
    exfuns_init();                  /* 为fatfs相关变量申请内存 */
    f_mount(fs[0], "0:", 1);        /* 挂载SD卡 */
    res = f_mount(fs[1], "1:", 1);  /* 挂载FLASH */
    
    if (res == 0X0D)                /* FLASH磁盘,FAT文件系统错误,重新格式化FLASH */
    {
        lcd_show_string(30, 150, 200, 16, 16, "Flash Disk Formatting...", RED);         /* 格式化FLASH */
        res = f_mkfs("1:", 0, 0, FF_MAX_SS);                                            /* 格式化FLASH,1:,盘符;0,使用默认格式化参数 */

        if (res == 0)
        {
            f_setlabel((const TCHAR *)"1:ALIENTEK");                                    /* 设置Flash磁盘的名字为：ALIENTEK */
            lcd_show_string(30, 150, 200, 16, 16, "Flash Disk Format Finish", RED);     /* 格式化完成 */
        }
        else
        {
            lcd_show_string(30, 150, 200, 16, 16, "Flash Disk Format Error ", RED);     /* 格式化失败 */
        }

        delay_ms(1000);
    }
    
    lcd_fill(30, 150, 240, 150 + 16, WHITE);    /* 清除显示 */

    while (exfuns_get_free("0", &total, &free)) /* 得到SD卡的总容量和剩余容量 */
    {
        lcd_show_string(30, 150, 200, 16, 16, "SD Card Fatfs Error!", RED);
        delay_ms(200);
        lcd_fill(30, 150, 240, 150 + 16, WHITE);/* 清除显示 */
        delay_ms(200);
    }

    lcd_show_string(30, 150, 200, 16, 16, "FATFS OK!", BLUE);
    lcd_show_string(30, 170, 200, 16, 16, "SD Total Size:     MB", BLUE);
    lcd_show_string(30, 190, 200, 16, 16, "SD Free Size:      MB", BLUE);
    lcd_show_num(30 + 8 * 14, 170, total >> 10, 5, 16, BLUE);               /* 显示SD卡总容量 MB */
    lcd_show_num(30 + 8 * 14, 190, free >> 10, 5, 16, BLUE);                /* 显示SD卡剩余容量 MB */
}
